<?php
/**
 * @since   2022-02-15
 * @author  zhaoxiang <zhaoxiang051405@gmail.com>
 */

namespace App\Controller\Admin;

use App\Constants\ErrorCode;
use App\Constants\RedisKey;
use App\Exception\CommonException;
use App\Middleware\AdminMiddleware;
use App\Model\AdminUser;
use App\Service\LoginService;
use App\Service\ToolService;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\PostMapping;
use Hyperf\Redis\RedisFactory;
use Hyperf\Context\ApplicationContext;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

#[Controller(prefix: '/admin/Login'), Middleware(AdminMiddleware::class)]
class LoginController extends BaseController {

    /**
     * 用户登录
     * @return array
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    #[PostMapping(path: 'index')]
    public function index(): array {
        $username = $this->request->input('username', '');
        $password = $this->request->input('password', '');
        $captcha  = $this->request->input('captcha');
        $uuid     = $this->request->input('uuid');

        if (!$username) {
            return $this->buildFailed(ErrorCode::LOGIN_ERROR, '缺少用户名!');
        }
        if (!$password) {
            return $this->buildFailed(ErrorCode::LOGIN_ERROR, '缺少密码!');
        }
        if (!$captcha) {
            return $this->buildFailed(ErrorCode::LOGIN_ERROR, '缺少验证码!');
        }

        $redis          = ApplicationContext::getContainer()->get(RedisFactory::class)->get('default');
        $sessionCaptcha = $redis->get($uuid);
        if (!$sessionCaptcha) {
            return $this->buildFailed(ErrorCode::LOGIN_ERROR, '验证码已过期!');
        }
        $redis->del($uuid);

        if (strtolower($captcha) !== strtolower($sessionCaptcha)) {
            return $this->buildFailed(ErrorCode::LOGIN_ERROR, '验证码不正确!');
        }

        $password = ToolService::userMd5($password);
        $userInfo = AdminUser::query()->where('username', $username)->where('password', $password)->first();
        if (!empty($userInfo)) {
            try {
                $res = (new LoginService())->doLogin($userInfo, $this->getIp());

                return $this->buildSuccess($res[0], $res[1]);
            } catch (CommonException $e) {
                return $this->buildFailed($e->getCode(), $e->getMessage());
            }
        }

        return $this->buildFailed(ErrorCode::LOGIN_ERROR, '用户名密码不正确');
    }

    /**
     * 获取用户信息
     * @author zhaoxiang <zhaoxiang051405@gmail.com>
     */
    #[GetMapping(path: 'getUserInfo')]
    public function getUserInfo(): array {
        $userDataArr = $this->uInfo();

        return $this->buildSuccess($userDataArr);
    }

    /**
     * 用户登出
     * @return array
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @author zhaoxiang <zhaoxiang051405@gmail.com>
     */
    #[GetMapping(path: 'logout')]
    public function logout(): array {
        $userDataArr = $this->uInfo();
        $redis       = ApplicationContext::getContainer()->get(RedisFactory::class)->get('default');
        $apiAuth     = $redis->get(RedisKey::ADMIN_LOGIN_ID . ':' . $userDataArr['id']);
        if ($apiAuth) {
            $redis->del(RedisKey::ADMIN_LOGIN_AUTH . ':' . $apiAuth);
            $redis->del(RedisKey::ADMIN_LOGIN_ID . ':' . $userDataArr['id']);
        }

        return $this->buildSuccess([], '登出成功');
    }

    /**
     * 获取当前用户的允许菜单
     * @author zhaoxiang <zhaoxiang051405@gmail.com>
     */
    #[GetMapping(path: 'getAccessMenu')]
    public function getAccessMenu(): array {
        $userDataArr = $this->uInfo();

        return $this->buildSuccess((new LoginService())->getAccessMenuData($userDataArr['id']));
    }

}
